/*-------------------------------------------------------------------------
 *
 * tqual.h
 *      POSTGRES "time qualification" definitions, ie, tuple visibility rules.
 *
 *      Should be moved/renamed...    - vadim 07/28/98
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * This source code file contains modifications made by THL A29 Limited ("Tencent Modifications").
 * All Tencent Modifications are Copyright (C) 2023 THL A29 Limited.
 * 
 * src/include/utils/tqual.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef TQUAL_H
#define TQUAL_H

#include "utils/snapshot.h"
#include "access/xlogdefs.h"


/* Static variables representing various special snapshot semantics */
extern PGDLLIMPORT SnapshotData SnapshotSelfData;
extern PGDLLIMPORT SnapshotData SnapshotAnyData;
extern PGDLLIMPORT SnapshotData CatalogSnapshotData;

#define SnapshotSelf        (&SnapshotSelfData)
#define SnapshotAny            (&SnapshotAnyData)
/*
#ifdef _MIGRATE_
#define SnapshotNow            (&SnapshotNowData)
#endif
*/

#ifdef _MIGRATE_
#define     SHARD_VISIBLE_MODE_VISIBLE     0
#define        SHARD_VISIBLE_MODE_HIDDEN   1
#define        SHARD_VISIBLE_MODE_ALL    2
#endif




/* This macro encodes the knowledge of which snapshots are MVCC-safe */
#define IsMVCCSnapshot(snapshot)  \
    ((snapshot)->satisfies == HeapTupleSatisfiesMVCC || \
     (snapshot)->satisfies == HeapTupleSatisfiesHistoricMVCC)

/*
 * HeapTupleSatisfiesVisibility
 *        True iff heap tuple satisfies a time qual.
 *
 * Notes:
 *    Assumes heap tuple is valid.
 *    Beware of multiple evaluations of snapshot argument.
 *    Hint bits in the HeapTuple's t_infomask may be updated as a side effect;
 *    if so, the indicated buffer is marked dirty.
 */
#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \
    ((*(snapshot)->satisfies) (tuple, snapshot, buffer))

/* Result codes for HeapTupleSatisfiesVacuum */
typedef enum
{
    HEAPTUPLE_DEAD,                /* tuple is dead and deletable */
    HEAPTUPLE_LIVE,                /* tuple is live (committed, no deleter) */
    HEAPTUPLE_RECENTLY_DEAD,    /* tuple is dead, but not deletable yet */
    HEAPTUPLE_INSERT_IN_PROGRESS,    /* inserting xact is still in progress */
    HEAPTUPLE_DELETE_IN_PROGRESS    /* deleting xact is still in progress */
} HTSV_Result;

/* These are the "satisfies" test routines for the various snapshot types */
extern bool HeapTupleSatisfiesMVCC(HeapTuple htup,
                       Snapshot snapshot, Buffer buffer);
extern bool HeapTupleSatisfiesSelf(HeapTuple htup,
                       Snapshot snapshot, Buffer buffer);
extern bool HeapTupleSatisfiesAny(HeapTuple htup,
                      Snapshot snapshot, Buffer buffer);
extern bool HeapTupleSatisfiesToast(HeapTuple htup,
                        Snapshot snapshot, Buffer buffer);
extern bool HeapTupleSatisfiesDirty(HeapTuple htup,
                        Snapshot snapshot, Buffer buffer);
extern bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup,
                               Snapshot snapshot, Buffer buffer);

#ifdef __STORAGE_SCALABLE__
extern bool HeapTupleSatisfiesUnshard(HeapTuple htup, Snapshot snapshot, Buffer buffer);
#endif

/* Special "satisfies" routines with different APIs */
extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTuple htup,
                         CommandId curcid, Buffer buffer);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup,
                         TransactionId OldestXmin, Buffer buffer);
extern bool HeapTupleIsSurelyDead(HeapTuple htup,
                      TransactionId OldestXmin);

extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
                     uint16 infomask, TransactionId xid);
extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);
/*
#ifdef _MIGRATE_
extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple,
                      Snapshot snapshot, Buffer buffer);

#endif
*/
/*
 * To avoid leaking too much knowledge about reorderbuffer implementation
 * details this is implemented in reorderbuffer.c not tqual.c.
 */
struct HTAB;
extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data,
                              Snapshot snapshot,
                              HeapTuple htup,
                              Buffer buffer,
                              CommandId *cmin, CommandId *cmax);

/*
 * We don't provide a static SnapshotDirty variable because it would be
 * non-reentrant.  Instead, users of that snapshot type should declare a
 * local variable of type SnapshotData, and initialize it with this macro.
 */
#define InitDirtySnapshot(snapshotdata)  \
    ((snapshotdata).satisfies = HeapTupleSatisfiesDirty)

/*
 * Similarly, some initialization is required for SnapshotToast.  We need
 * to set lsn and whenTaken correctly to support snapshot_too_old.
 */
#define InitToastSnapshot(snapshotdata, l, w)  \
    ((snapshotdata).satisfies = HeapTupleSatisfiesToast, \
     (snapshotdata).lsn = (l),                    \
     (snapshotdata).whenTaken = (w))

#endif                            /* TQUAL_H */
